<?php

namespace App\Kuafu\Shop\Controller\B;

use App\Exceptions\BaseException;
use App\Exceptions\CustomValidateException;
use App\Kuafu\Base\Controller\BaseController;
use App\Kuafu\Base\Enum\BaseCodeEnum;
use App\Kuafu\Base\Service\BaseService;
use App\Kuafu\Common\Service\CommonService;
use App\Kuafu\CouponExt\Channel\MeiTuan\MeiTuanBase;
use App\Kuafu\Invoice\Service\MoredoBaseService;
use App\Kuafu\Shop\Enum\CodeEnum;
use App\Kuafu\Shop\Enum\ShopCodeEnum;
use App\Kuafu\Shop\Exceptions\ShopException;
use App\Kuafu\Shop\Jobs\SyncCameraJob;
use App\Kuafu\Shop\Model\CameraModel;
use App\Kuafu\Shop\Model\Shop;
use App\Kuafu\Shop\Resources\B\ShopArchivesResource;
use App\Kuafu\Shop\Resources\B\ShopListResource;
use App\Kuafu\Shop\Service\DouyinShopService;
use App\Kuafu\Shop\Service\DouyinShopV2Service;
use App\Kuafu\Shop\Service\ShopArchivesService;
use App\Kuafu\Shop\Service\ShopAttributeService;
use App\Kuafu\Shop\Service\ShopCameraService;
use App\Kuafu\Shop\Service\ShopInvoiceService;
use App\Kuafu\Shop\Service\ShopService;
use App\Kuafu\Shop\Validate\ShopInvoiceValidate;
use App\Kuafu\Shop\Validate\ShopNewValidate;
use App\Kuafu\Shop\Validate\ShopValidate;
use App\Kuafu\User\Service\AuthService;
use App\Kuafu\WaiMai\Enum\WaiMaiDBEnum;
use App\Kuafu\WaiMai\Exceptions\WaiMaiException;
use App\Kuafu\WaiMai\Service\WaiMaiShopService;
use App\Library\KfHttp\TigerCurl;
use GuzzleHttp\Exception\GuzzleException;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Routing\Redirector;
use Illuminate\Support\Facades\Artisan;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Redis;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;

class ShopController extends BaseController
{

    /**
     * 新增店铺
     * @param $request
     * @return JsonResponse
     */
    public function addShop(Request $request)
    {
        $valid = ShopValidate::addOrSetShop($request);
        if ($valid) {
            return $this->fail(ShopCodeEnum::ERR_SHOP_INSERT, $valid);
        }
        ShopService::addShop($request);
        return $this->success();
    }

    /**
     * 获取店铺信息
     * @param Request $request
     * @return JsonResponse
     */
    public function getShopInfo(Request $request)
    {
        if (empty($request->shopId)) {
            $this->fail(ShopCodeEnum::ERR_400000);
        }
        $info = ShopService::getShopInfoShow($request->shopId);

        // camera
        $info['cameraList'] = ShopCameraService::getShopCameraList($request->shopId, CameraModel::SUPPLIER_ALIYUN);
        $info['archives']   = ShopArchivesService::getArchivesInfo($request->shopId);

        return $this->success($info);
    }

    /**
     * @param Request $request
     * @return JsonResponse
     */
    public function getShopListByBrandId(Request $request): JsonResponse
    {
        $name     = $request->get('name', '');
        $pageSize = (int)$request->get('pageSize', 20);
        $pageNum  = (int)$request->get('pageNum', 1);
        $status   = $request->get('status');
        $dimCode  = $request->get('dimCode', '');

        $field = [
            'id',
            "shopCode",
            'name',
            'shortName',
            'shopMobile',
            'address',
            'type',
            'status',
            'createdByUid',
            'updatedByUid',
            'updatedAt',
            'createdAt',
            'createdByUid',
            'startAt',
            'endAt',
            'invoice',
            'dyCouponVerifySwitch'
        ];


        $query = Shop::getShopListByBrandPage($request->brandId, $pageSize, $pageNum, $status, $name, $field, $dimCode);

        if ($query->count()) {
            $shopIds  = $query->pluck('id')->toArray();
            $feeTimes = collect(TigerCurl::getIns()
                                         ->do('callback/fee/getFeeTime', ['shopIds' => $shopIds], 'GET')['data'])
                ->keyBy('shopId');
        } else {
            $feeTimes = collect();
        }

        return $this->success([
            'pageSize' => $query->perPage(),
            'pageNum'  => $query->currentPage(),
            'count'    => $query->total(),
            'lists'    => collect(ShopListResource::collection($query->items()))
                ->map(function ($item) use ($feeTimes) {
                    $item['feeDate']     = $feeTimes[$item['id']]['startFeeTime'] ?? '-';
                    $item['showEditFee'] = $item['feeDate'] == '-' ? 0 : 1;
                    return $item;
                }),
        ]);
    }

    /**
     * @param Request $request
     * @return JsonResponse
     */
    public function getAllShopList(Request $request): JsonResponse
    {
        $name     = $request->get('name', '');
        $pageSize = (int)$request->get('pageSize', 99999);
        $pageNum  = (int)$request->get('pageNum', 1);
        $status   = $request->get('status');

        $field = [
            'id',
            "shopCode",
            'name',
            'shopMobile',
            'address',
            'type',
            'status',
            'createdByUid',
            'updatedByUid',
            'updatedAt',
            'createdAt',
            'createdByUid',
            'startAt',
            'endAt',
            'invoice'
        ];

        $query = Shop::getShopListByBrandPage($request->brandId, $pageSize, $pageNum, $status, $name, $field);

        $list       = ShopListResource::collection($query->items());
        $returnList = [];
        foreach ($list as $one) {
            $returnList[] = [
                'id'       => $one['id'],
                'shopCode' => str_pad($one['shopCode'], ShopCodeEnum::CODE_TEXT[ShopCodeEnum::LEADING_ZERO],
                    "0", STR_PAD_LEFT),
                'name'     => $one['name']
            ];
        }
        return $this->success([
            'lists' => $returnList,
        ]);
    }


    public function getShopList(Request $request)
    {
        $res = ShopService::getShopList($request);

        return $this->success($res);
    }

    /**
     * 编辑店铺信息
     * @param $request
     * @return JsonResponse
     */
    public function setShopInfo(Request $request)
    {
        $valid = ShopValidate::addOrSetShop($request);
        if ($valid) {
            return $this->fail(ShopCodeEnum::ERR_SHOP_INSERT, $valid);
        }
        ShopService::setShopInfo($request);
        return $this->success();
    }

    public function setShopStatus(Request $request)
    {
        $valid = ShopValidate::setShopStatus($request);
        if ($valid) {
            return $this->fail(ShopCodeEnum::ERR_PARAM_PATH_ERROR, $valid);
        }
        ShopService::setShopStatus($request->shopId, $request->status);
        return $this->success();
    }

    public function deletedShop(Request $request)
    {
        if (empty($request->shopId)) {
            $this->fail(ShopCodeEnum::ERR_400000);
        }
        ShopService::deletedShop($request);
        return $this->success();
    }

    /**
     * 绑定店铺的菜单
     * @param Request $request
     * @return JsonResponse
     */
    public function bindProductMenu(Request $request)
    {
        $valid = ShopValidate::bindProductMenu($request);
        if ($valid) {
            return $this->fail(ShopCodeEnum::ERR_SHOP_INPUT, $valid);
        }

        ShopService::bindProductMenu($request);

        return $this->success();
    }

    /**
     * 查询店铺绑定的菜单
     * @param Request $request
     * @return JsonResponse
     */
    public function getBindProductMenu(Request $request)
    {
        $shopId = (int)$request->get('shopId', 0);
        if (!$shopId) {
            return $this->fail(ShopCodeEnum::ERR_SHOP_ID_NO_EXIST);
        }
        $shop = ShopService::getShopInfo($shopId);

        return $this->success(['data' => ['productMenuId' => $shop->menuId ?? 0]]);
    }

    /**
     * 查询绑了xx菜单的店铺
     * @param Request $request
     * @return JsonResponse
     */
    public function getBindMenuShops(Request $request)
    {
        $productMenuId = $request->get('productMenuId');
        $pageSize      = $request->get('pageSize', 10);
        $pageNum       = $request->get('pageNum', 1);

        $valid = ShopValidate::getBindMenuShops($request);
        if ($valid) {
            return $this->fail(ShopCodeEnum::ERR_SHOP_INPUT, $valid);
        }

        $list = Shop::getShopsByMenuId($productMenuId);
        return $this->success([
            'list' => $list
        ]);
    }

    /**
     * 跳转到美团团购绑定店铺后台
     * @param Request $request
     * @param $shopId
     * @return Application|RedirectResponse|Redirector
     */
    public function toBindMtShop(Request $request, $shopId)
    {
        $url = (new MeiTuanBase((int)$shopId, false))->storeMap();
        return redirect($url);
    }

    /**
     * 绑定外卖店铺
     * @param Request $request
     * @param $shopId
     * @return JsonResponse
     * @throws ShopException
     * @throws WaiMaiException
     */
    public function toBindWaiMaiShop(Request $request, $shopId): JsonResponse
    {
        $thirdShopId = (string)$request->post('thirdShopId', '');
        $sourceType  = (int)$request->post('sourceType');

        if ($shopId === $thirdShopId) {
            return $this->fail(BaseCodeEnum::ERR_400000, "这里应该填外卖平台的门店ID");
        }

        (new WaiMaiShopService($shopId))->bindWaiMai($thirdShopId, $sourceType);

        return $this->success();
    }

    /**
     * 解绑外卖店铺
     * @param Request $request
     * @param $shopId
     * @return JsonResponse
     * @throws WaiMaiException
     */
    public function toUnbindWaiMaiShop(Request $request, $shopId)
    {
        $sourceType = (int)$request->post('sourceType');

        (new WaiMaiShopService($shopId))->unbindWaiMai($sourceType);

        return $this->success();
    }

    /**
     * 门店富有支付配置新增
     *
     * @param Request $request
     * @param $shopId
     * @return JsonResponse
     * @throws ShopException
     */
    public function shopFuYouPaymentsInsert(Request $request, $shopId): JsonResponse
    {
        list($errMsg, $requestParams) = ShopValidate::shopPaymentsInsertValidate($request->all());
        if ($errMsg) {
            return $this->fail(BaseCodeEnum::ERR_400000, $errMsg);
        }
        ShopService::shopPaymentsInsert($requestParams, auth()->id(), $shopId);
        return $this->success([]);
    }

    /**
     * 门店富有支付配置新增
     *
     * @param Request $request
     * @param $shopId
     * @param $paymentId
     * @return JsonResponse
     * @throws ShopException
     */
    public function shopFuYouPaymentsEdit(Request $request, $shopId, $paymentId): JsonResponse
    {
        list($errMsg, $requestParams) = ShopValidate::shopPaymentsEditValidate(
            $request->merge(['paymentId' => $paymentId, 'shopId' => $shopId])->all()
        );
        if ($errMsg) {
            return $this->fail(BaseCodeEnum::ERR_400000, $errMsg);
        }

        ShopService::shopPaymentsEdit($requestParams, auth()->id(), $shopId);
        return $this->success([]);
    }

    /*
     * 门店开票信息编辑
     *
     * @param Request $request
     * @param $shopId
     * @return JsonResponse
     * @throws ShopException
     */
    public function shopInvoice(Request $request, $shopId): JsonResponse
    {
        list($errMsg, $requestParams) = ShopInvoiceValidate::shopInvoiceEditValidate($request->all());

        if ($errMsg) {
            return $this->fail(BaseCodeEnum::ERR_400000, $errMsg);
        }
        ShopInvoiceService::shopInvoiceUpdate($requestParams, $shopId);
        //添加税盘
        if (isset($requestParams['moredo'])) {
            MoredoBaseService::addDevice($requestParams['moredo']['invoiceNo'], $requestParams['moredo']['kpjh']);
        }
        return $this->success([]);
    }

    /**
     * @param Request $request
     * @param $shopId
     * @return JsonResponse
     * @throws ShopException
     * @throws WaiMaiException
     */
    public function bandDouYinShop(Request $request, $shopId)
    {
        $valid = ShopValidate::bandDouYinSHop($request);
        if ($valid) {
            return $this->fail(BaseCodeEnum::ERR_400000, $valid);
        }
        $sourceType    = (int)$request->post('sourceType');
        $thirdShopName = (string)$request->post('thirdShopName');
        $thirdShopId   = (string)$request->post('thirdShopId');
        DouyinShopService::bandDouYinShopMapping($sourceType, $shopId, $thirdShopId, $thirdShopName);
        return $this->success();
    }

    /**
     * @param Request $request
     * @param $shopId
     * @return JsonResponse
     * @throws ShopException
     * @throws WaiMaiException
     */
    public function unBandDouYinShop(Request $request, $shopId)
    {
        $sourceType = WaiMaiDBEnum::SOURCE_TYPE_DOUYIN;
        DouyinShopService::unBandDouYinShopMapping($sourceType, $shopId);
        return $this->success();
    }

    /**
     * 模糊搜索抖音店铺
     * @param Request $request
     * @return JsonResponse
     */
    public function searchDouYinShopInfo(Request $request)
    {
        $thirdShopId = $request->thirdShopId ?? '';
        $shopInfo    = DouyinShopService::handleDouYinShopListV2($thirdShopId);
        return $this->success($shopInfo);
    }

    /**
     * 查询小红书门店列表
     *
     * @param Request $request
     * @return JsonResponse
     * @throws BaseException
     * @throws CustomValidateException
     * @throws GuzzleException
     * @throws ContainerExceptionInterface
     * @throws NotFoundExceptionInterface
     */
    public function searchXhsShopList(Request $request): JsonResponse
    {
        $params = ShopNewValidate::searchXhsShopListValidate($request->all());
        return $this->success(ShopService::searchXhsShopList($params));
    }

    /**
     * @param Request $request
     * @return JsonResponse
     * @throws BaseException
     * @throws ContainerExceptionInterface
     * @throws CustomValidateException
     * @throws GuzzleException
     * @throws NotFoundExceptionInterface
     */
    public function bindXhsShop(Request $request): JsonResponse
    {
        $params = ShopNewValidate::bindXhsShopValidate($request->all());
        ShopService::bindXhsShop($params);
        return $this->success();
    }

    /**
     * @param Request $request
     * @return JsonResponse
     * @throws BaseException
     * @throws ContainerExceptionInterface
     * @throws CustomValidateException
     * @throws NotFoundExceptionInterface
     */
    public function unbindXhsShop(Request $request): JsonResponse
    {
        $params = ShopNewValidate::unbindXhsShopValidate($request->all());
        ShopService::unbindXhsShop($params);
        return $this->success();
    }

    /**
     * 门店选择器
     * @param Request $request
     * @return JsonResponse
     * @throws ContainerExceptionInterface
     * @throws CustomValidateException
     * @throws NotFoundExceptionInterface
     */
    public function shopSelect(Request $request): JsonResponse
    {
        $params = ShopNewValidate::shopSelectValidate($request->all());

        $isCity       = attributeGet($params, 'isCity', 0);// 只返回分公司-城市
        $status       = attributeGet($params, 'status', '');// 加门店状态
        $openFyStatus = attributeGet($params, 'openFyStatus', 0);// 加富友配置
        $isDistrict   = attributeGet($params, 'isDistrict', 0);// 返回省市区+门店

        return $this->success(ShopService::shopSelect($isCity, $status, $openFyStatus, $isDistrict));
    }

    public function syncYlkCamera(Request $request): JsonResponse
    {
        $shopId = $request->get('shopId') ?? 0;

        // 加锁
        $redis_key     = 'syncYlkCamera:' . $shopId;
        $expireSeconds = 600;
        if (!Redis::setnx($redis_key, time())) {
            // 防止死锁
            $lock_time = Redis::get($redis_key);
            if (($lock_time + $expireSeconds) < time()) {
                Redis::del($redis_key);
            } else {
                return $this->fail(200, '更新任务正在进行中, 请稍后再试!');
            }
        }

        // 清除这个门店的缓存
        $shopInfo = ShopService::getShopInfo($shopId);

        if (empty($shopInfo)) {
            return $this->fail(200, '门店不存在!');
        }

        ShopService::updateShopInfo(['id' => $shopInfo->id], ['cameraSupplierId' => 0]);

        // 更新这个门店的摄像头
        Artisan::call('tools:import-ylk');

        SyncCameraJob::dispatch($shopId)->onQueue(SyncCameraJob::$QUEUE_NAME);

        return $this->success();
    }

    /**
     * 抖音券码核销开关
     *
     * @param Request $request
     * @return JsonResponse
     * @throws BaseException
     * @throws ContainerExceptionInterface
     * @throws CustomValidateException
     * @throws NotFoundExceptionInterface
     */
    public function dyCouponVerifySwitch(Request $request): JsonResponse
    {
        $params = ShopNewValidate::dyCouponVerifySwitchValidate($request->all());
        ShopService::dyCouponVerifySwitch($params);
        return $this->success();
    }

    /**
     * 修改门店信息-单个字段
     * @param Request $request
     * @param int $shopId
     * @return JsonResponse
     * @throws ShopException
     */
    public function updateField(Request $request, int $shopId)
    {
        $this->validate($request, [
            'eWechatUrl' => 'string',
            'eWechatPic' => 'string',
        ]);
        $data = [];
        if ($request->eWechatUrl) {
            $data['shopArchives']['eWechatUrl'] = $request->eWechatUrl;
        }
        if ($request->eWechatPic) {
            $data['shopArchives']['eWechatPic'] = $request->eWechatPic;
        }
        if (!$data) {
            return $this->fail(BaseCodeEnum::NOT_FOUND, '参数不存在');
        }
        ShopService::updateField($shopId, $data);
        return $this->success();
    }

    /**
     * 获取门店属性
     * @param Request $request
     * @param int $shopId
     * @return JsonResponse
     */
    public function getShopAttribute(Request $request, int $shopId): JsonResponse
    {
        return $this->success(ShopAttributeService::getShopAttribute([$shopId])[$shopId] ?? []);
    }

    /**
     * 编辑门店属性
     * @param Request $request
     * @param int $shopId
     * @return JsonResponse
     */
    public function updateShopAttribute(Request $request, int $shopId): JsonResponse
    {
        $data['status']                    = (string)$request->get('status', '');// 门店状态
        $data['shopType']                  = (string)$request->get('shopType', '');// 店型
        $data['siteSelection']             = (string)$request->get('siteSelection', '');// 选址场景
        $data['siteSelectionGrade']        = (string)$request->get('siteSelectionGrade', '');// 场景等级
        $data['posLine']                   = (string)$request->get('posLine', '');// 点餐动线
        $data['engineeringExhibitionArea'] = (string)$request->get('engineeringExhibitionArea', '');// 工程条件-展面
        $data['engineeringArea']           = (string)$request->get('engineeringArea', '');// 工程条件-面积
        $data['engineeringElectricity']    = (string)$request->get('engineeringElectricity', '');// 工程条件-电量
        $data['engineeringDepth']          = (string)$request->get('engineeringDepth', '');// 工程条件-进深
        $data['menuLevel']                 = (string)$request->get('menuLevel', '');// 菜单等级
        $data['sellingCategory']           = (string)$request->get('sellingCategory', '');// 售卖品类
        $data['posType']                   = (string)$request->get('posType', '');// 收银设备
        $data['tags']                      = (string)$request->get('tags', '');// 关联标签

        $rmsUserId = auth('api')->user()->id;
        return $this->success(ShopAttributeService::updateShopAttribute($shopId, $rmsUserId, $data, 1));
    }

    /**
     * 获取门店属性筛选项
     * @param Request $request
     * @return JsonResponse
     */
    public function getShopAttributeSearch(Request $request): JsonResponse
    {
        return $this->success(ShopAttributeService::getAttributeList());
    }

    /**
     * 门店筛选通过门店属性
     * @param Request $request
     * @return JsonResponse
     */
    public function getShopByAttributeSearch(Request $request): JsonResponse
    {
        $name              = (string)$request->get('name', '');// 门店编号/门店名称搜索
        $data['condition'] = (string)$request->get('condition', '');// any-满足任一条件 all-满足所有条件
        $list              = $request->get('list', '');// 参数
        $data['list']      = [];
        if ($list) {
            $data['list'] = json_decode(urldecode($list), true) ?? [];
        }
        return $this->success(ShopAttributeService::getShopByAttributeSearch($name, $data));
    }
}
